package cn.huiyunche.base.service.interfaces.impl;

import cn.huiyunche.base.service.constant.QiniuConstant;
import cn.huiyunche.base.service.constant.YeePayConstant;
import cn.huiyunche.base.service.enums.*;
import cn.huiyunche.base.service.framework.utils.HYCUtils;
import cn.huiyunche.base.service.framework.utils.QiniuUtils;
import cn.huiyunche.base.service.interfaces.CAccntBalanceService;
import cn.huiyunche.base.service.interfaces.CashService;
import cn.huiyunche.base.service.interfaces.SendMessageService;
import cn.huiyunche.base.service.interfaces.UserService;
import cn.huiyunche.base.service.mappers.*;
import cn.huiyunche.base.service.model.*;
import cn.huiyunche.base.service.utils.DateUtils;
import cn.huiyunche.base.service.vo.*;
import cn.huiyunche.base.service.yeepay.utils.CallbackUtils;
import cn.huiyunche.base.service.yeepay.utils.Digest;
import cn.huiyunche.base.service.yeepay.utils.PaymobileUtils;
import cn.huiyunche.tools.basic.exceptions.BusinessException;
import com.cfca.util.pki.PKIException;
import com.cfca.util.pki.api.CertUtil;
import com.cfca.util.pki.api.KeyUtil;
import com.cfca.util.pki.api.SignatureUtil;
import com.cfca.util.pki.cert.X509Cert;
import com.cfca.util.pki.cipher.JCrypto;
import com.cfca.util.pki.cipher.JKey;
import com.cfca.util.pki.cipher.Session;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.xml.sax.InputSource;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;

/**
 * 提现
 *
 * @author hdy [Tuffy]
 */
@Service
public class CashServiceImpl implements CashService {

    private static final Logger LOGGER = LoggerFactory.getLogger(CashServiceImpl.class);

    /**
     * 绑定卡最大条数
     */
    private final int max_cardlist_count = 5;

    /**
     * 银行卡前缀
     */
    private final String bank_cark_prefix = "**** **** **** ";

    /**
     * 提现订单号前缀
     */
    private final String order_id_prefix = "hyc_";
    /**
     * 提现订单号最大长度
     */
    private final int order_id_max_length = 46;
    /**
     * 易宝session
     */
    private Session tempsession = null;
    /**
     * 易宝签名工具
     */
    private SignatureUtil signUtil = null;


    @Autowired
    private UserService userService = null;

    @Autowired
    private SendMessageService sendMessageService = null;

    @Autowired
    private CUserBankcardMapper cUserBankcardMapper = null;

    @Autowired
    private BBankMapper bBankMapper = null;

    @Autowired
    private SUserMapper sUserMapper = null;

    @Autowired
    private CDriverCertinfoMapper cDriverCertinfoMapper = null;

    @Autowired
    private CAccntBalanceService cAccntBalanceService = null;

    @Autowired
    private CWithdrawLogMapper cWithdrawLogMapper = null;

    @Override
    public Result<String> bindBankCard(BindBankCardVo bbcv) throws Exception {
        LOGGER.info("bindBankCard param : {}", bbcv);
        /*String card = "6228480402564890019";
		this.getSendMessageService().sendCashMsg("13241999036", card.substring(card.length() - 4, card.length()), 1000.00 + "");*/
        Result<String> r = new Result<>(true);
        /**校验数据*/
        // 用户基本信息校验
        this.checkBindUser(bbcv, r);
        if (!r.isSuccess()) {
            return r;
        }
        // 卡信息校验
        this.checkBindBankCard(bbcv, r);
        if (!r.isSuccess()) {
            return r;
        }
        // 卡校验
        Result<Object> cardR = checkBankCard(bbcv.getBankCard());
        if (!cardR.isSuccess()) {
            r.setMessage(cardR.getMessage());
            return r;
        }
        // 密码认证
        r = this.getCAccntBalanceService().checkPwd(bbcv.getCashPwd());
        if (!r.isSuccess()) {
            return r;
        }
        // 绑定数据
        this.insertBindBankCard(bbcv, r, cardR);
        return r;
    }

    @Override
    public Result<String> unBindBankCard(String cardId, String cashPwd) {
        LOGGER.info("unBindBankCard params : {}, {}", cardId, cashPwd);
        // 卡信息、用户认证
        Result<String> r = new Result<>(false);
        CUserBankcard ubc = this.getCUserBankcardMapper().selectByPrimaryKey(NumberUtils.toLong(HYCUtils.decryptBankCard(cardId)));
        if (null == ubc) {
            r.setMessage("卡信息不存在");
            return r;
        }
        // 密码认证
        r = this.getCAccntBalanceService().checkPwd(cashPwd);
        if (!r.isSuccess()) {
            return r;
        }
        // 解绑卡信息
        ubc.setEnable(EnabledEnum.F.getValue());
        ubc.setIsDelete(EnabledEnum.T.getValue());
        ubc.setUpdateTime(new Date());
        this.getCUserBankcardMapper().updateByPrimaryKey(ubc);
        r.setMessage("解绑成功");
        r.setSuccess(true);
        return r;
    }

    @Override
    public Result<List<OutUserBankCardVo>> myBankCards() throws Exception {
        // 加密卡列表
        Result<List<OutUserBankCardVo>> r = new Result<>(true);
        UserShowVo usv = null;
        usv = this.getUserService().getCurrentUser();
        CUserBankcardExample userUbcs = new CUserBankcardExample();
        userUbcs.createCriteria().andUserIdEqualTo(usv.getId()).andEnableEqualTo(EnabledEnum.T.getValue())
                .andIsDeleteEqualTo(EnabledEnum.F.getValue());
        List<CUserBankcard> userList = this.getCUserBankcardMapper().selectByExample(userUbcs);
        List<OutUserBankCardVo> list = new ArrayList<>();
        for (CUserBankcard ubc : userList) {
            String code = HYCUtils.decryptBankCard(ubc.getCode());
            BBank b = this.getBBankMapper().selectByPrimaryKey(ubc.getBankId());
            if (null == b) {
                b = new BBank();
            }
            String bankLogoBucket = HYCUtils.getConstantPropertiesLoader().getProperty(QiniuConstant.QINIU_BANK_LOGO_BUCKET);
            list.add(new OutUserBankCardVo(HYCUtils.encryptBankCard(ubc.getId().longValue() + ""),
                    bank_cark_prefix + code.substring(code.length() - 4, code.length()),
                    b.getName(), QiniuUtils.generateDownloadTicket(bankLogoBucket, b.getLogo(), "", "", ""),
                    QiniuUtils.generateDownloadTicket(bankLogoBucket, b.getLogoSecond(), "", "", ""),
                    QiniuUtils.generateDownloadTicket(bankLogoBucket, b.getBackgroundLogo(), "", "", ""),
                    b.getLogoColor()));
        }
        r.setData(list);
        return r;
    }

    /**
     * 人送项目 司机提现申请
     *
     * @param cashPwd
     * @param amount
     * @return
     */
    @Override
    public Result<String> submitSettlementAppli(String cashPwd, BigDecimal amount) {
        return this.getCAccntBalanceService().submitSettlementAppli(cashPwd, amount);
    }

    /**
     * 提现操作
     *
     * @param cardId    提现卡id
     * @param cardId    卡id
     * @param cashPwd   提现密码
     * @param isUrgency 是否加急
     * @param quickcash 是否是快速提现 0:不是 1:是
     * @param score     是否是快速提现 0:不使用 1:使用
     * @return 结果集
     */
    @Override
    public Result<String> cashMyCost(String cardId, String cashPwd, String isUrgency, BigDecimal amount, Integer quickcash, Integer score) throws Exception {
        LOGGER.info("cash cost params cardId : {}, cashPwd : {}, isUrgency : {}, amount : {}, quickcash : {}, score : {}.", cardId, cashPwd, isUrgency, amount, quickcash, score);
        Result<String> r = new Result<>();
        // 卡认证、用户
        YeepayUserBankVo yub = this.getUserBankInfo(cardId);
        if (StringUtils.isBlank(yub.getCard()) || null == yub.getUserid()) {
            r.setSuccess(false);
            r.setMessage("用户信息或卡信息错误");
            return r;
        }
        //  密码认证
        r = this.getCAccntBalanceService().checkPwd(cashPwd);
        LOGGER.info("cash this.getCAccntBalanceService().checkPwd(cashPwd); r : {}.", r);
        if (!r.isSuccess()) {
            return r;
        }
        // 提现日判断
		/*String cashDay = DateUtils.getCurrentZeroDate("dd");
		String syCashPay = HYCUtils.getConstantPropertiesLoader().getProperty(YeePayConstant.YEEPAY_CASH_DAY);
		if (!cashDay.equals(syCashPay)) {
			r.setSuccess(false);
			r.setMessage("每月" + syCashPay + "号为提现日");
			return r;
		}*/
        // 系统金额判断 打到用户账户的钱要扣除手续费
        Result<Object> rAmount = this.getCAccntBalanceService().withdrawalByCard(amount.abs().negate(), quickcash, score, cashPwd);
        LOGGER.info("cash this.getCAccntBalanceService().withdrawalByCard(amount.abs().negate(), score, cashPwd); rAmount : {}.", rAmount);
        if (!rAmount.isSuccess()) {
            r.setMessage(rAmount.getMessage());
            r.setSuccess(false);
            return r;
        }
        if (rAmount.getData() != null) {
            amount = (BigDecimal) rAmount.getData();
        }
        tempsession = null; // 重置
        // 调用易宝接口
        try {
            String batchNo = DateUtils.getCurrentZeroDate(DateUtils.FORMAT_DATETIME_NO_SEPARATOR);
            BBank bb = this.getBBankMapper().selectByPrimaryKey(yub.getBankId());
            String responseMsg = CallbackUtils.httpRequest(HYCUtils.getConstantPropertiesLoader().getProperty(YeePayConstant.YEEPAY_CASH_URL),
                    this.getXmlRequest(new YeepayCashVo(cardId, new DecimalFormat("#.00").format(amount.abs().doubleValue()), isUrgency,
                            batchNo, this.getOrderId(batchNo), bb.getCode())), "POST", "gbk", "text/xml ;charset=gbk", false);
            String phone = yub.getPhone();
            String card = yub.getCard();
            r = this.parseResponseXml(responseMsg, batchNo, amount, cashPwd, phone, card);
            if (r.isSuccess()) {
                // 发送短信
                this.getSendMessageService().sendCashMsg(phone, card.substring(card.length() - 4, card.length()), amount.doubleValue() + "");
            }
            return r;
        } catch (Exception e) {
            LOGGER.info("cashMyCost error : {}.", e);
            throw new BusinessException("提现调用银行卡信息异常");
        }
    }

    @Override
    public Result<Object> checkBankCard(String card) {
        LOGGER.info("checkBankCard param : {}", card);
        Result<Object> r = new Result<>(false);
        TreeMap<String, Object> treeMap = new TreeMap<String, Object>();
        treeMap.put("cardno", card.replaceAll(" ", ""));
        //第一步 生成AESkey及encryptkey
        String AESKey = PaymobileUtils.buildAESKey();
        String encryptkey = PaymobileUtils.buildEncyptkey(AESKey);
        //第二步 生成data
        String data = PaymobileUtils.buildData(treeMap, AESKey);
        //第三步 http请求，银行卡信息查询接口的请求方式为POST
        String merchantaccount = PaymobileUtils.getMerchantaccount();
        String url = PaymobileUtils.getRequestUrl(PaymobileUtils.CHECKBANKCARDAPI_NAME);
        TreeMap<String, String> responseMap = PaymobileUtils.httpPost(url, merchantaccount, data, encryptkey);
        //第四步 判断请求是否成功
        if (responseMap.containsKey("error_code")) {
            r.setMessage(responseMap.get("error_msg"));
            return r;
        }
        //第五步 请求成功，则获取data、encryptkey，并将其解密
        String data_response = responseMap.get("data");
        String encryptkey_response = responseMap.get("encryptkey");
        TreeMap<String, String> responseDataMap = PaymobileUtils.decrypt(data_response, encryptkey_response);
        //第六步 sign验签
        if (!PaymobileUtils.checkSign(responseDataMap)) {
            r.setMessage("sign验签失败");
            return r;
        }
        //第七步 判断请求是否成功
        if (responseMap.containsKey("error_code")) {
            r.setMessage("sign验签失败");
            return r;
        }
        // 业务处理
        String cardtype = responseDataMap.get("cardtype");
        String bankname = responseDataMap.get("bankname");
        String isvalid = responseDataMap.get("isvalid");
        String bankcode = responseDataMap.get("bankcode");
        // 判断是否为借记卡
        if (!cardtype.equals(YeepayCardTypeEnum.DEBIT.getValue())) {
            r.setMessage("卡类型不是借记卡");
            return r;
        }
        // 卡是否可用
        if (!isvalid.equals(YeepayCardValidEnum.YES.getValue())) {
            r.setMessage("此卡不可用");
            return r;
        }
        // 返回结果
        Map<String, String> m = new HashMap<>();
        m.put("bankname", bankname);
        m.put("cardtype", YeepayCardTypeEnum.getByValue(cardtype).getText());
        m.put("bankcode", bankcode);
        r.setData(m);
        r.setSuccess(true);
        return r;
    }


    /**
     * 解析返回xml数据
     *
     * @param responseMsg xml数据
     * @return 结果集
     * @throws IOException
     * @throws JDOMException
     * @throws PKIException
     */
    private Result<String> parseResponseXml(String responseMsg, String batchNo, BigDecimal amount, String cashPwd, String phone, String card) throws JDOMException, IOException, PKIException {
        LOGGER.info("parseResponseXml params : {}, {}, {}, {}, {}, {}", responseMsg, batchNo, amount, cashPwd, phone, card);
        Result<String> r = new Result<>(false);
        SAXBuilder builder = new SAXBuilder();
        Document xml = null;
        //第五步:对服务器响应报文进行验证签名
        boolean sigerCertFlag = false;
        StringReader xmlReader = new StringReader(responseMsg);
        InputSource xmlSource = new InputSource(xmlReader);
        xml = builder.build(xmlSource);
        Element root = xml.getRootElement();
        String hmacStr = root.getChildText("hmac");
        //  记录日志
        CWithdrawLog cwl = this.insertDrawLog(root, batchNo, amount, phone, card);
        if (StringUtils.isNotBlank(hmacStr)) {
            sigerCertFlag = signUtil.p7VerifySignMessage(hmacStr.getBytes(), tempsession);
            String backmd5hmac = "";
            if (sigerCertFlag) {
                System.out.println("证书验签成功");
                backmd5hmac = new String(signUtil.getSignedContent());
                System.out.println("证书验签获得的MD5签名数据为----" + backmd5hmac);
                System.out.println("证书验签获得的证书dn为----" + new String(signUtil.getSigerCert()[0].getSubject()));
                if (this.parseBackSign(builder, responseMsg, backmd5hmac)) {
                    // 第八步:.......加上业务逻辑
                    CWithdrawLog updateCwl = new CWithdrawLog();
                    updateCwl.setId(cwl.getId());
                    updateCwl.setUpdateTime(new Date());
                    this.cWithdrawLogMapper.updateByPrimaryKeySelective(updateCwl);

                    r.setSuccess(true);
                    r.setMessage("提现成功");
                    return r;
                }
            }
        }
        // 回写金额到数据库
        this.getCAccntBalanceService().upBalanceByWithdrawal(cwl.getId(), amount, cashPwd);
        return r;
    }

    /**
     * 添加日志
     *
     * @param root
     * @param batchNo
     * @param amount
     * @return
     */
    private CWithdrawLog insertDrawLog(Element root, String batchNo, BigDecimal amount, String phone, String card) {
        LOGGER.info("insertDrawLog params : {}, {}, {}, {}, {}", root, batchNo, amount, phone, card);
        CWithdrawLog cwl = new CWithdrawLog();
        cwl.setAmt(amount);
        cwl.setBankStat(root.getChildText("bank_Status"));
        cwl.setBatchId(batchNo);
        // cwl.setCallbackRetCode(callbackRetCode);
        // cwl.setCallbackRetTime(callbackRetTime);
        cwl.setHmac(root.getChildText("hmac"));
        cwl.setLogTime(new Date());
        cwl.setMsg(root.getChildText("error_Msg"));
        cwl.setOrderId(root.getChildText("order_Id"));
        cwl.setRetCode(root.getChildText("ret_Code"));
        cwl.setStatCode(root.getChildText("r1_Code"));
        cwl.setPhone(phone);
        cwl.setCardno(card);
        this.getCWithdrawLogMapper().insert(cwl);
        return cwl;
    }

    /**
     * 解析返回数据验证
     *
     * @param responseMsg
     * @return
     * @throws IOException
     * @throws JDOMException
     * @throws PKIException
     */
    private boolean parseBackSign(SAXBuilder builder, String responseMsg, String backmd5hmac) throws JDOMException, IOException, PKIException {
        //第六步.将验签出来的结果数据与自己针对响应数据做MD5签名之后的数据进行比较是否相等
        StringReader xmlReader = new StringReader(responseMsg);
        InputSource xmlSource = new InputSource(xmlReader);
        YeepayBackXmlRequestVo ybxrv = new YeepayBackXmlRequestVo(builder.build(xmlSource));
        // ybxrv cmd、ret_Code、r1_Code
        StringBuffer sb = new StringBuffer("");
        sb.append(ybxrv.getCmd().getText()).append(ybxrv.getRetCode().getText()).append(ybxrv.getR1Code().getText())
                .append(HYCUtils.getConstantPropertiesLoader().getProperty(YeePayConstant.YEEPAY_GROUP_CA));
        String newmd5hmac = Digest.hmacSign(sb.toString());
        System.out.println("提交返回源数据为---||" + backmd5hmac + "||");
        System.out.println("经过md5签名后的验证返回hmac为---||" + newmd5hmac + "||");
        System.out.println("提交返回的hmac为---||" + backmd5hmac + "||");
        if (newmd5hmac.equals(backmd5hmac)) {
            System.out.println("md5验签成功");
            // 第七步:判断该证书DN是否为易宝
            if (signUtil.getSigerCert()[0].getSubject().toUpperCase().indexOf("OU=YEEPAY,") > 0) {
                System.out.println("证书DN是易宝的");
                return true;
            }
            System.out.println("证书DN不是易宝的");
        }
        return false;
    }

    /**
     * 根据批次号生成订单id
     *
     * @param batchNo 批次号
     * @return 订单id
     */
    private String getOrderId(String batchNo) {
        LOGGER.info("getOrderId param : {}", batchNo);
        String encryptBatchNo = HYCUtils.encryptBankCard(batchNo);
        if (encryptBatchNo.length() > order_id_max_length) {
            encryptBatchNo.substring(0, order_id_max_length);
        }
        return order_id_prefix + encryptBatchNo;
    }

    /**
     * 设置请求报文
     *
     * @param ycv 报文参数实体
     * @return 结果集
     * @throws PKIException
     * @throws UnsupportedEncodingException
     */
    private String getXmlRequest(YeepayCashVo ycv) throws Exception {
        String groupId = HYCUtils.getConstantPropertiesLoader().getProperty(YeePayConstant.YEEPAY_GROUP_ID);
        YeepayUserBankVo yubv = this.getUserBankInfo(ycv.getCardId());
        YeepayXmlRequestVo yxr = new YeepayXmlRequestVo(YeepayCmdEnum.SINGLE.getValue(), groupId, groupId, ycv.getBatchNo(),
                ycv.getOrderId(), ycv.getBankCode(), ycv.getAmount() + "", yubv.getName(), yubv.getCard(), ycv.getIsUrgency(), null);
        yxr.setHmac(this.signHmac(yxr));

        Document xml = yxr.getXml();
        XMLOutputter XMLOut = new XMLOutputter();
        Format f = Format.getPrettyFormat();
        f.setEncoding("GBK");
        XMLOut.setFormat(f);
        return XMLOut.outputString(xml);
    }

    /**
     * 签名证书
     *
     * @return
     * @throws PKIException
     * @throws UnsupportedEncodingException
     */
    private String signHmac(YeepayXmlRequestVo yxr) throws PKIException, UnsupportedEncodingException {
        // 需要排序字符串
        StringBuffer hmacStr = new StringBuffer("");
        // cmd、mer_Id、 batch_No、order_Id、amount 、 account_Number、hmacKey
        String hmacKey = HYCUtils.getConstantPropertiesLoader().getProperty(YeePayConstant.YEEPAY_GROUP_CA);
        hmacStr.append(yxr.getCmd()).append(yxr.getMerId()).append(yxr.getBatchNo()).append(yxr.getOrderId())
                .append(yxr.getAmount()).append(yxr.getAccountNumber()).append(hmacKey);
        String ALGORITHM = SignatureUtil.SHA1_RSA;
        JCrypto jcrypto = null;
        if (tempsession == null) {
            // 初始化加密库，获得会话session
            // 多线程的应用可以共享一个session,不需要重复,只需初始化一次
            // 初始化加密库并获得session。
            // 系统退出后要jcrypto.finalize()，释放加密库
            jcrypto = JCrypto.getInstance();
            jcrypto.initialize(JCrypto.JSOFT_LIB, null);
            tempsession = jcrypto.openSession(JCrypto.JSOFT_LIB);
            String classPath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
            String keyString = classPath + File.separator + HYCUtils.getConstantPropertiesLoader().getProperty(YeePayConstant.YEEPAY_KEY_PFX_NAME);
            String certString = classPath + File.separator + HYCUtils.getConstantPropertiesLoader().getProperty(YeePayConstant.YEEPAY_KEY_PFX_NAME);
            // 证书添加
            JKey jkey = KeyUtil.getPriKey(keyString, HYCUtils.getConstantPropertiesLoader().getProperty(YeePayConstant.YEEPAY_KEY_PASSWORD));
            X509Cert cert = CertUtil.getCert(certString, HYCUtils.getConstantPropertiesLoader().getProperty(YeePayConstant.YEEPAY_CERTP_PASSWORD));
            System.out.println(cert.getSubject());
            X509Cert[] cs = new X509Cert[1];
            cs[0] = cert;
            String signMessage = "";
            // 第二步:对请求的串进行MD5对数据进行签名
            String yphs = Digest.hmacSign(hmacStr.toString());
            signUtil = new SignatureUtil();
            byte[] b64SignData;
            // 第三步:对MD5签名之后数据调用CFCA提供的api方法用商户自己的数字证书进行签名
            b64SignData = signUtil.p7SignMessage(true, yphs.getBytes(), ALGORITHM, jkey, cs, tempsession);
            if (jcrypto != null) {
                jcrypto.finalize(com.cfca.util.pki.cipher.JCrypto.JSOFT_LIB, null);
            }
            signMessage = new String(b64SignData, "UTF-8");
            // System.out.println("经过md5和数字证书签名之后的数据为---||" + signMessage + "||");
            return signMessage;
        }
        return null;
    }

    /**
     * 获取用户卡信息
     *
     * @param cardId 卡id
     * @return
     */
    private YeepayUserBankVo getUserBankInfo(String cardId) throws Exception {
        YeepayUserBankVo yubv = new YeepayUserBankVo();
        CUserBankcard cub = this.getCUserBankcardMapper().selectByPrimaryKey(NumberUtils.toLong(HYCUtils.decryptBankCard(cardId)));
        if (null != cub) {
            yubv.setCard(HYCUtils.decryptBankCard(cub.getCode()));
            yubv.setBankId(cub.getBankId());
        }
        UserShowVo usv = null;
        usv = this.getUserService().getCurrentUser();
        if (null != usv) {
            yubv.setName(usv.getRealName());
            yubv.setUserid(usv.getId());
            yubv.setPhone(usv.getPhone());
        }
        return yubv;
    }

    /**
     * 校验数据合法性
     *
     * @param bbcv 带校验信息
     * @return 结果集
     */
    private void checkBindUser(BindBankCardVo bbcv, Result<String> r) throws Exception {
        Long id = this.getUserService().getCurrentUserVo().getId();
        SUser user = this.getSUserMapper().selectByPrimaryKey(id);
        if (user.getUserType() != UserTypeEnum.DRIVER.getValue() && user.getUserType() != UserTypeEnum.SEND_DRIVER.getValue()) {
            r.setSuccess(false);
            r.setMessage("当前用户类型不为司机");
            return;
        }
        if (!bbcv.getUserName().equals(user.getRealName())) {
            r.setSuccess(false);
            r.setMessage("为了您的账户资金安全，只能绑定认证司机本人银行卡");
            return;
        }
		/*if (!user.getPhone().equals(bbcv.getPhone())) {
			r.setSuccess(false);
			r.setMessage("用户预留手机号不匹配");
			return;
		}*/
        // 判断是否是中联司机
        if (!this.userService.isTmsUser(user.getPhone())) {
            CDriverCertinfoExample cdceUser = new CDriverCertinfoExample();
            cdceUser.createCriteria().andUserIdEqualTo(id);
            List<CDriverCertinfo> listUser = this.getCDriverCertinfoMapper().selectByExample(cdceUser);
            CDriverCertinfo cdc = listUser.size() > 0 ? listUser.get(0) : null;
            if (null == cdc) {
                r.setSuccess(false);
                r.setMessage("司机信息不存在");
                return;
            }
            if (user.getUserType() != UserTypeEnum.DRIVER.getValue() && !cdc.getStatus().equals(TruckAuditStatusEnum.AUDIT_PASS.getValue())) {
                r.setSuccess(false);
                r.setMessage("当前用户未认证");
                return;
            }
			/*CDriverCertinfoExample cdce = new CDriverCertinfoExample();
			cdce.createCriteria().andIdnoEqualTo(HYCUtils.encryptBankCard(bbcv.getIdCard()));
			List<CDriverCertinfo> list = this.getCDriverCertinfoMapper().selectByExample(cdce);
			if (list.size() != 1) {
				r.setSuccess(false);
				r.setMessage("用户身份证信息不匹配");
				return;
			}*/
        }
    }

    /**
     * 校验卡信息
     *
     * @param bbcv 待校验数据
     * @param r    结果集
     */
    private void checkBindBankCard(BindBankCardVo bbcv, Result<String> r) throws Exception {
        String bankCard = bbcv.getBankCard();
        String encodeCard = HYCUtils.encryptBankCard(bankCard.replaceAll(" ", ""));
        CUserBankcardExample ubcs = new CUserBankcardExample();
        ubcs.createCriteria().andCodeEqualTo(encodeCard).andEnableEqualTo(EnabledEnum.T.getValue())
                .andIsDeleteEqualTo(EnabledEnum.F.getValue());
        List<CUserBankcard> list = this.getCUserBankcardMapper().selectByExample(ubcs);
        if (list.size() > 0) {
            r.setMessage("此银行卡已被绑定，请核对您的银行卡号，再次绑定。");
            r.setSuccess(false);
            return;
        }
        UserShowVo usv = null;
        usv = this.getUserService().getCurrentUser();
        CUserBankcardExample userUbcs = new CUserBankcardExample();
        userUbcs.createCriteria().andUserIdEqualTo(usv.getId()).andEnableEqualTo(EnabledEnum.T.getValue())
                .andIsDeleteEqualTo(EnabledEnum.F.getValue());
        List<CUserBankcard> userList = this.getCUserBankcardMapper().selectByExample(userUbcs);
        if (userList.size() >= max_cardlist_count) {
            r.setMessage("用户最多只能绑定5张银行卡");
            r.setSuccess(false);
            return;
        }

    }

    /**
     * 添加卡数据
     *
     * @param bbcv
     * @param r
     */
    private void insertBindBankCard(BindBankCardVo bbcv, Result<String> r, Result<Object> cardR) throws Exception {
        @SuppressWarnings("unchecked")
        Map<String, String> data = (HashMap<String, String>) cardR.getData();
        String bankcode = data.get("bankcode");
        CUserBankcard ubc = new CUserBankcard();
        // 获取银行信息
        BBankExample bs = new BBankExample();
        bs.createCriteria().andCodeEqualTo(bankcode);
        List<BBank> list = this.getBBankMapper().selectByExample(bs);
        BBank b = list.size() > 0 ? list.get(0) : null;
        if (null == b) {
            r.setMessage("获取银行卡信息失败");
            r.setSuccess(false);
            return;
        }
        UserShowVo usv = null;
        usv = this.getUserService().getCurrentUser();
        // 保存信息
        ubc.setBankId(b.getId());
        ubc.setCode(HYCUtils.encryptBankCard(bbcv.getBankCard()));
        ubc.setCreateTime(new Date());
        ubc.setEnable(EnabledEnum.T.getValue());
        ubc.setIsDelete(EnabledEnum.F.getValue());
        ubc.setUpdateTime(new Date());
        ubc.setUserId(usv.getId());
        this.getCUserBankcardMapper().insert(ubc);
        r.setMessage("绑定成功");
        r.setSuccess(true);
    }

    private UserService getUserService() {
        return this.userService;
    }

    private CUserBankcardMapper getCUserBankcardMapper() {
        return this.cUserBankcardMapper;
    }

    private SUserMapper getSUserMapper() {
        return this.sUserMapper;
    }

    private BBankMapper getBBankMapper() {
        return this.bBankMapper;
    }

    private CAccntBalanceService getCAccntBalanceService() {
        return this.cAccntBalanceService;
    }

    private CDriverCertinfoMapper getCDriverCertinfoMapper() {
        return this.cDriverCertinfoMapper;
    }

    private CWithdrawLogMapper getCWithdrawLogMapper() {
        return this.cWithdrawLogMapper;
    }

    private SendMessageService getSendMessageService() {
        return this.sendMessageService;
    }

}